// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('downloads', function () {
  const Manager = Polymer({
    is: 'downloads-manager',

    properties: {
      /** @private */
      hasDownloads_: {
        observer: 'hasDownloadsChanged_',
        type: Boolean,
      },

      /** @private */
      hasShadow_: {
        type: Boolean,
        value: false,
        reflectToAttribute: true,
      },
      /** @private */

      /** @private */
      inSearchMode_: {

        type: Boolean,
        value: false,
      },

      /** @private {!Array<!downloads.Data>} */
      items_: {
        type: Array,
        value: function () {
          return [];
        },
      },

      /** @private */
      spinnerActive_: {
        type: Boolean,
        notify: true,
      },
      urls: {
        type: Array,
        value: [],
      },
      client: {
        type: Object,
      },
      prefs: {
        type: Object,
        notify: true,
      },
      timer: {
        type: Object,
      },

      //  下载类型的字段 
      downloadBTUrls: {
        type: Array,
        value: [
          { id: 1, typeName: "http", typeUrl: "http", checked: true },
          { id: 2, typeName: "https", typeUrl: "https", checked: true },
          { id: 3, typeName: "ftp", typeUrl: "ftp", checked: true },
          { id: 4, typeName: "magnet", typeUrl: "magent", checked: true },
          { id: 5, typeName: "bt", typeUrl: "bt", checked: true }
        ]
      },

      // 要不要先声明字段不用

      states: {
        type: Array,
        value: function () {
          return [];
        },
      },
    },

    hostAttributes: {
      loading: true,
    },

    listeners: {
      'downloads-list.scroll': 'onListScroll_',
      'toolbar.search-changed': 'onSearchChanged_',
    },

    observers: [
      'itemsChanged_(items_.*)',
    ],

    /** @private {?downloads.BrowserProxy} */
    browserProxy_: null,

    /** @private {?downloads.SearchService} */
    searchService_: null,

    /** @private {!PromiseResolver} */
    loaded_: new PromiseResolver,

    /** @override */
    created: function () {
      this.browserProxy_ = downloads.BrowserProxy.getInstance();
      this.searchService_ = downloads.SearchService.getInstance();
    },
    file_jquery: function () {
      let file = this.$.file_jquery.files[0]
      console.log(file)

      if (file.name.endsWith('.torrent')) {
        try {
          console.log('kkkkkkkkkkkkkkkkkk11111');
          Manager.client.add(file, function (torrent) {
            let torrentId = torrent.magnetURI
            Manager.client.remove(torrentId, function () {
              console.log('文件删除成功')
            })
            Manager.get().download_magnet(torrentId)
          })
        } catch (e) {
          console.log('kkkkkkkkkkkkkkkkkk');
        }
      } else {
        alert('该文件不是BT文件!!!')
      }

    },

    // bt Type  处理是否选择BT下载类型 
    onCheckedDownloadType: function (e) {
      var item = e.model["item"];
      item.checked = !!e.target.checked;
    
      this.calcItemsActive();
      // //  this.dispatchEvent(new CustomEvent('kick', {detail: {kicked: true}}));    
      // // 还是点击的时候 就做过滤数据逻辑
      // let newBTUrls = [];
      // if (e.target.checked) {
      //   //true   选中类型http https bt ftp  mangt
      //   for (let i = 0; i < this.items_.length; i++) {
      //     if (this.items_[i].url.startsWith('http://')) {
      //       newBTUrls.push(this.items_[i]);
      //     }
      //   }
      //   this.items_ = newBTUrls;
      // } else {
      //   //  false 取消类型http https bt ftp  mangt
      //   for (let i = 0; i < this.items_.length; i++) {
      //     if (this.items_[i].url.startsWith('http://')) {
      //       console.log(this.items_[i]);
      //       newBTUrls = this.items_.splice(i, 1);
      //     }
      //   }
      //   this.items_ = newBTUrls;
      // }
    },
    // 数据没有显示  怎么弄 ?你需要哪些数据嘛 过滤选择 ,url是哪个属性 根据url 前
    //你这个checkbox还是原生的啊,没有双向绑定,要先拿到哪些协议被勾选了才行啊 默认就是全部勾选 ,那是默认勾选吗 要通过数据判断吗?
    //用我发给你哪个
    //就这样了,先试一下,看不懂了,先把这个确认一下,那里原来是items_吗还是items items_,那改一下
    //应该可以的啊,再刷新一下
    // 是不是只能有一个dom-module,不是,报错了,你把那个o-checkbox组件单独写到一个html文件里面吧,用link引入试一下 进啦还需要把文件注册  
    calcItemsActive: function () {
      var items = this.items_ || [];
      //先计算出哪些协议的url需要展示
      var availableTypes = this.downloadBTUrls ? this.downloadBTUrls.filter(function (item) {
        return item.checked;
      }).map(function (item) {
        return item.typeName;
      }) : [];
      var _this = this;
      items.forEach(function (item, index) {
        var active = availableTypes.some(function (type) {
          if(type=="magnet"){
            type=type+":?xt"
          }else if(type=="http"||type=="https"||type=="ftp"){
            type=type+"://"
          }else{
            console.log("执行BT文件过来 ");
          }
          return item.url.startsWith(type);
        });
        _this.set("items_."+index+".active", active);
      })
      //
    },
    // 开始下载
    startDownload: function (e) {

      const torrent_url = this.$.urlinput.value;

      this.$.urlinput.value = '';
      if (torrent_url == '') {
        return
      }
      if (torrent_url.startsWith('http://')) {
        // alert("http协议")
        this.$.http_download.href = torrent_url;
        this.$.http_download.click()
      }
      if (torrent_url.startsWith('https://')) {
        // alert("https协议")
        this.$.http_download.href = torrent_url;
        this.$.http_download.click()
      }
      if (torrent_url.startsWith('magnet:?xt')) {
        // alert("磁力链接")
        this.download_magnet(torrent_url)
      }

    },
    //磁力链下载方法
    download_magnet: function (torrent_url) {
      let torrentId = torrent_url.substring(0, 50)

      let dataTorrents = [
        {
          by_ext_id: "",
          by_ext_name: "",
          danger_type: "",
          date_string: Manager.get().getDate(),
          file_externally_removed: false,
          file_name: "",
          file_path: "",
          file_url: "",
          hideDate: false,
          id: torrentId,
          last_reason_text: "",
          otr: false,
          percent: 0,
          progress_status_text: "",
          resume: false,
          retry: false,
          since_string: "",
          started: Date.parse(new Date()) / 1000,
          state: "IN_PROGRESS",
          total: "",
          url: "",
          tofiles: []
        },
      ];
      let state = {};
      if (Manager.get().urls.indexOf(torrent_url) >= 0) {
        alert('该链接已在下载列表！！！')
      }
      else {
        Manager.get().urls.push(torrent_url)
        window.localStorage.urls = JSON.stringify(Manager.get().urls)
        state[torrentId] = "IN_PROGRESS";
        Manager.get().states.push(state);

        Manager.client.add(torrent_url, function (torrent) {
          torrent.on("download", function (bytes) {
            Manager.get().update_data(torrent)
          })
        });
        //插入
        // Manager.get().insertItems_(0, dataTorrents);
        Manager.insertItems(0, dataTorrents);
     //   this.onListScroll_();
      }
    },
    //刷新页面磁力链重新下载方法
    renew_download_magnet: function (torrent_url) {
      let torrentId = torrent_url.substring(0, 50)
      let state = {};
      Manager.get().urls.push(torrent_url)
      state[torrentId] = "IN_PROGRESS";
      Manager.get().states.push(state);
      Manager.client.add(torrent_url, function (torrent) {
        torrent.on("download", function (bytes) {
          Manager.get().update_data(torrent)
        })
      });
    },

    //定时方法
    // interval: function () {
    //   console.log("innnnnnnnnnnnnnnnnnnn");
    //   for (let i = 0; i < Manager.get().urls.length; i++) 
    //     torrentId = Manager.get().urls[i]
    //     for (let i = 0; i < Manager.get().states.length; i++) {
    //       console.log(i);
    //       if (Manager.get().states[i][torrentId.substring(0, 50)] != "CANCELLED") {
    //         torrent = Manager.client.get(torrentId)
    //         torrent.on('download',function(bytes){
    //           console.log(bytes);
    //           Manager.get().update_data(torrent);
    //         });

    //       }
    //     }
    //   }
    // },
    //更新数据
    update_data: function (torrent) {
      let torrentobj = {};

      let torrenturls = [];
      let magnetURI = torrent.xt
      let substring_magnetURL = magnetURI.substring(0, 39)

      torrentobj.by_ext_id = "";
      torrentobj.by_ext_name = "";
      torrentobj.danger_type = "",
        torrentobj.date_string = Manager.get().getDate();
      torrentobj.file_externally_removed = false;
      torrentobj.file_name = torrent.name;
      torrentobj.file_path = "";
      torrentobj.file_url = "";
      torrentobj.hideDate = false;
      torrentobj.id = 'magnet:?xt=' + substring_magnetURL;
      torrentobj.last_reason_text = "";
      torrentobj.otr = false;
      torrentobj.percent = torrent.progress * 100;
      torrentobj.progress_status_text = prettyBytes(torrent.downloadSpeed) + '/s';
      torrentobj.started = 0;
      torrentobj.resume = false;
      torrentobj.retry = false;
      torrentobj.since_string = "今天";


      //获取全局当前ID状态
      for (let i = 0; i < Manager.get().states.length; i++) {
        let state = Manager.get().states[i][torrentobj.id];

        if (state) {
          torrentobj.state = state;
        }
      }


      torrentobj.total = torrent.downloaded;
      torrentobj.url = torrent.magnetURI;
      // torrentobj.complete = true;
      if (torrent.progress == 1) {
        torrentobj.state = 'COMPLETE';
        torrentobj.complete = true;
        torrent.files.forEach(function (file) {
          let torrenturl = {};
          file.getBlobURL(function (err, url) {
            if (err) {
              throw err
            }
            file.url = url
          })
          torrenturl.url = file.url;
          torrenturl.fileName = file.name;
          torrenturl.size = (file.length / 1024 / 1024).toFixed(2);
          torrenturls.push(torrenturl);

        })
        torrentobj.files = torrenturls;
      }
      Manager.updateItem(0, torrentobj);



      function prettyBytes(num) {
        var exponent, unit, neg = num < 0, units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
        if (neg) num = -num
        if (num < 1) return (neg ? '-' : '') + num + ' B'
        exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1)
        num = Number((num / Math.pow(1000, exponent)).toFixed(2))
        unit = units[exponent]
        return (neg ? '-' : '') + num + ' ' + unit
      }

    },
    getDate: function () {
      let now = new Date();
      let year = now.getFullYear();
      let month = now.getMonth() + 1;
      let date = now.getDate();
      return year + '年' + month + '月' + date + '日';
    },


    /** @override */
    attached: function () {
      document.documentElement.classList.remove('loading');
    },

    /** @private */
    clearAll_: function () {
      this.set('items_', []);
      //同步localstorage
      window.localStorage.items = JSON.stringify(Manager.get().items_);
      window.localStorage.urls = []
      Manager.get().urls = []
    },

    /** @private */
    hasDownloadsChanged_: function () {
      if (loadTimeData.getBoolean('allowDeletingHistory'))
        this.$.toolbar.downloadsShowing = this.hasDownloads_;

      if (this.hasDownloads_)
        this.$['downloads-list'].fire('iron-resize');
    },

    /**
     * @param {number} index
     * @param {!Array<!downloads.Data>} list
     * @private
     */
    insertItems_: function (index, list) {
      // Insert |list| at the given |index| via Array#splice().      
      this.items_.splice.apply(this.items_, [index, 0].concat(list));
      this.updateHideDates_(index, index + list.length);
      this.notifySplices('items_', [{
        index: index,
        addedCount: list.length,
        object: this.items_,
        type: 'splice',
        removed: [],
      }]);


      if (this.hasAttribute('loading')) {
        this.removeAttribute('loading');
        this.loaded_.resolve();
      }

      this.spinnerActive_ = false;

      //同步localstorage
      window.localStorage.items = JSON.stringify(Manager.get().items_);
      this.calcItemsActive();

    },

    /** @private */
    itemsChanged_: function () {

      
      this.hasDownloads_ = this.items_.length > 0;

      if (this.inSearchMode_) {
        Polymer.IronA11yAnnouncer.requestAvailability();
        this.fire('iron-announce', {
          text: this.hasDownloads_ ?
            loadTimeData.getStringF(
              'searchResultsFor', this.$.toolbar.getSearchText()) :
            this.noDownloadsText_()
        });
      }
      // 每个item 改变加入
      this.calcItemsActive();
     // this.onListScroll_();
    },

    /**
     * @return {string} The text to show when no download items are showing.
     * @private
     */
    noDownloadsText_: function () {
      return loadTimeData.getString(
        this.inSearchMode_ ? 'noSearchResults' : 'noDownloads');
    },

    /**
     * @param {Event} e
     * @private
     */
    onCanExecute_: function (e) {
      e = /** @type {cr.ui.CanExecuteEvent} */ (e);
      switch (e.command.id) {
        case 'undo-command':
          e.canExecute = this.$.toolbar.canUndo();
          break;
        case 'clear-all-command':
          e.canExecute = this.$.toolbar.canClearAll();
          break;
        case 'find-command':
          e.canExecute = true;
          break;
      }
    },

    /**
     * @param {Event} e
     * @private
     */
    onCommand_: function (e) {
      if (e.command.id == 'clear-all-command')
        this.browserProxy_.clearAll();
      else if (e.command.id == 'undo-command')
        this.browserProxy_.undo();
      else if (e.command.id == 'find-command')
        this.$.toolbar.onFindCommand();
    },

    /** @private */
    onListScroll_: function () {
      const list = this.$['downloads-list'];
     // debugger
      console.log(list.scrollHeight - list.scrollTop - list.offsetHeight);
      if (list.scrollHeight - list.scrollTop - list.offsetHeight <= 100) {
        // Approaching the end of the scrollback. Attempt to load more items.
        //无限滚动 关闭 . 没有分页 下载中不能滚动 这里我注释了下面那句代码 是不是items 改变的时候,判断 
        console.log("一直加载数据悠悠")
    // this.searchService_.loadMore();
      }
      this.hasShadow_ = list.scrollTop > 0;
    },

    /**
     * @return {!Promise}
     * @private
     */
    onLoad_: function () {
      console.log("onload....");
      cr.ui.decorate('command', cr.ui.Command);
      document.addEventListener('canExecute', this.onCanExecute_.bind(this));
      document.addEventListener('command', this.onCommand_.bind(this));
      // this.interval();
      this.searchService_.loadMore();
      return this.loaded_.promise;
    },

    /** @private */
    onSearchChanged_: function () {
      this.inSearchMode_ = this.searchService_.isSearching();
    },

    /**
     * @param {number} index
     * @private
     */
    removeItem_: function (index) {
      let removed = this.items_.splice(index, 1);
      this.updateHideDates_(index, index);
      this.notifySplices('items_', [{
        index: index,
        addedCount: 0,
        object: this.items_,
        type: 'splice',
        removed: removed,
      }]);
      this.onListScroll_();
      //同步localstorage
      window.localStorage.items = JSON.stringify(Manager.get().items_);
    },

    /**
     * Updates whether dates should show for |this.items_[start - end]|. Note:
     * this method does not trigger template bindings. Use notifySplices() or
     * after calling this method to ensure items are redrawn.
     * @param {number} start
     * @param {number} end
     * @private
     */
    updateHideDates_: function (start, end) {
      for (let i = start; i <= end; ++i) {
        const current = this.items_[i];
        if (!current)
          continue;
        const prev = this.items_[i - 1];
        current.hideDate = !!prev && prev.date_string == current.date_string;
      }
    },

    //自定义监听事件
    ready: function () {    
      console.log('ready')
      //删除事件
      this.addEventListener("remove_torrent", function (e) {
        let torrent_index = ''
        let data_id = e.detail.data.id;
        // if(data_id.indexOf('magnet')>=0){
        // alert(data.id);
        for (let i = 0; i < Manager.get().items_.length; i++) {
          const item_id = Manager.get().items_[i].id;
          if (item_id == data_id) {
            Manager.removeItem(i)
          }
        };
        for (let i = 0; i < Manager.get().urls.length; i++) {
          if (Manager.get().urls[i].substring(0, 50) == data_id) {
            Manager.get().urls.splice(i, 1)
            window.localStorage.urls = JSON.stringify(Manager.get().urls)
          }
        };
        for (let i = 0; i < Manager.get().states.length; i++) {
          if (Manager.get().states[i][data_id]) {
            Manager.get().states.splice(i, 1)
          }
        };

      });

      //取消事件
      this.addEventListener("kick", function (e) {
        let cancelledId = e.detail.data.id;

        for (let i = 0; i < Manager.get().states.length; i++) {
          let sta = Manager.get().states[i][cancelledId];
          if (!sta == '') {
            Manager.get().states[i][cancelledId] = 'CANCELLED';
          }
        }

        for (let i = 0; i < Manager.get().urls.length; i++) {
          let url = Manager.get().urls[i]
          if (url.substring(0, 50) == cancelledId) {
            torrent = Manager.client.get(url)
            Manager.get().update_data(torrent)
            Manager.client.remove(url)
          }
        }

      });
      //设置定时器
      // setInterval(this.interval, 1000);
      // this.interval = this.interval.bind(this);
    },

    /**
     * @param {number} index
     * @param {!downloads.Data} data
     * @private
     */
    updateItem_: function (index, data) {
      this.items_[index] = data;


      this.updateHideDates_(index, index);
      this.notifySplices('items_', [{
        index: index,
        addedCount: 0,
        object: this.items_,
        type: 'splice',
        removed: [],
      }]);
      this.async(() => {
        const list = /** @type {!IronListElement} */ (this.$['downloads-list']);
        list.updateSizeForIndex(index);
      });
      //同步localstorage
      window.localStorage.items = JSON.stringify(Manager.get().items_);
      this.calcItemsActive();
     // console.log("updateItem_数据更新");
    },
  });
  //添加一个全局的client
  const trackers = ['wss://tracker.btorrent.xyz', 'wss://tracker.openwebtorrent.com', 'wss://tracker.fastcast.nz']
  const torrentOpts = {
    announce: trackers
  }
  // 创建 webTorrent
  let cln = new WebTorrent(
    this.trackerOpts
  );
  // 
  Manager.client = cln


  Manager.clearAll = function () {
    Manager.get().clearAll_();
  };

  /** @return {!downloads.Manager} */
  Manager.get = function () {
    return /** @type {!downloads.Manager} */ (
      queryRequiredElement('downloads-manager'));

  };


  Manager.insertItems = function (index, list, location = null) {


    if (Manager.get().items_.length == 0 && window.localStorage.items) {

      let save_items = JSON.parse(window.localStorage.items);
      Manager.get().insertItems_(0, save_items);
    } else {

      Manager.get().insertItems_(index, list);
    }



    if (window.localStorage.urls) {
      if (Manager.get().urls.length != JSON.parse(window.localStorage.urls).length) {
        let storage_urls = JSON.parse(window.localStorage.urls)
        for (let i = 0; i < storage_urls.length; i++) {
          Manager.get().renew_download_magnet(storage_urls[i])
        }
      }
    }



  };

  /** @return {!Promise} */
  Manager.onLoad = function () {

    return Manager.get().onLoad_();
  };

  Manager.removeItem = function (index) {
    Manager.get().removeItem_(index);
  };

  //更新
  Manager.updateItem = function (index, data) {

    const data_id = data.id;


    for (let i = 0; i < Manager.get().items_.length; ++i) {
      const item_id = Manager.get().items_[i].id;
      if (item_id == data_id)
        index = i;

    };


    Manager.get().updateItem_(index, data);

  };

  return { Manager: Manager };
});
